"use strict"
// import * as THREE from './three'
const World = {
    MAX_X : 300,                // 世界的尺寸
    MAX_Y : 300,
    MAX_Z : 300,
    Total_height : 227.72,

}

const times = 1;

const Aperture_size = {
    Ground_anode : 2.96 * times,
    Min_hole : 0.5 * times,
    Lock_1 : 6.0 * times,
    Lock_2 : 2.0 * times,
    Tube : 3.0 * times,
}

// const Aperture_size = {
//     Ground_anode : 29.6,
//     Min_hole : 5,
//     Lock_1 : 60,
//     Lock_2 : 20,
//     Tube : 30,
// }

const Outer_size = 50;

const Aperture_posi = {
    Ground_anode : 22.25,
    Min_hole : 105.85,
    Lock_1 : 111.65,
    Lock_2 : 128.27,
    Tube : 132.15,
    Direct_camera : 150,
}

const Gun = {
    Angle_x : 0,    // 方向在xy平面内与y轴负方向的夹角
    Angle_z : 0,    // 方向在xz平面内与y轴负方向的夹角
    Filament_height : 0,
    Anode_size : 0.4,
    Anode_height : 7.05,
    Spin_center_height : 3.0 // the spin center of the whole gun
}

// 初始化相机和页面canvas元素，开启投影
const scene = new THREE.Scene();
const camera_global = new THREE.PerspectiveCamera(50,window.innerWidth / window.innerHeight,0.1,1000);
const renderer_global = new THREE.WebGLRenderer();
renderer_global.shadowMap.enabled = true;
renderer_global.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
camera_global.position.set(World.MAX_X*0.9,World.MAX_Y/2,World.MAX_Z*0.9);
camera_global.lookAt(0,World.MAX_Y/4,0);
renderer_global.setSize(window.innerWidth/2,window.innerHeight/2);
document.body.appendChild(renderer_global.domElement);

// 直接看下方的光点，对应从电子枪内部向下看荧光屏图像
const camera_direct = new THREE.PerspectiveCamera(120,window.innerWidth / window.innerHeight,0.1,1000);
const renderer_direct = new THREE.WebGLRenderer();

renderer_direct.shadowMap.enabled = true;
renderer_direct.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
camera_direct.position.set(0,World.Total_height - Aperture_posi.Direct_camera,0);
camera_direct.lookAt(0,0,0)
renderer_direct.setSize(window.innerWidth/2,window.innerHeight/2);
document.body.appendChild(renderer_direct.domElement);

const axesHelper = new THREE.AxesHelper( World.MAX_X );
scene.add( axesHelper );

var amlight = new THREE.AmbientLight(0x003300);
scene.add(amlight);

// light source

// a line to help us see the direction
// 需要一根细线指示发射方向
const materialine = new THREE.LineBasicMaterial( { color: 0x0000ff } );
const points = [];
points.push( new THREE.Vector3(0, World.Total_height - Gun.Filament_height, 0 ) );
points.push( new THREE.Vector3( 0, 0, 0 ) );
const geometryline = new THREE.BufferGeometry().setFromPoints( points );
const pointing_line = new THREE.Line( geometryline, materialine );
scene.add( pointing_line );

const electron_beam = new THREE.SpotLight( 0xffffff );  // 点光源模型
// 电子束被阳极孔和肖特基极孔遮挡。角度会跟着变化
electron_beam.position.set(0,World.Total_height - Gun.Filament_height,0)
electron_beam.castShadow = true; // default false
electron_beam.intensity = 10;
scene.add( electron_beam );

const anode_geometry = new THREE.RingGeometry( Gun.Anode_size, Outer_size,65536);
const anode_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const anode_mesh = new THREE.Mesh( anode_geometry, anode_material );

anode_mesh.castShadow = true; //default is false
anode_mesh.receiveShadow = false; //default
anode_mesh.rotateX(Math.PI / 2);
anode_mesh.position.y = World.Total_height - Gun.Anode_height;
scene.add( anode_mesh );

// 需要控制旋转方向

// 需要一个可以跟着旋转的阳极孔。旋转中心可以调节。暂定就在光源和孔的连线中央高度处
function rotate_gun(phi_x, phi_z) {
    // mesh.position.y = posi_y - Math.cos(phi_x) * dis;
    // mesh.position.x = Math.sin(phi_x) * dis ;
    // mesh.rotation.y = (phi_x);
    var rotate_center_height = -10;
    // electron_beam.position.set()
    anode_mesh.position.y = World.Total_height - rotate_center_height - (Gun.Anode_height - rotate_center_height)*Math.cos(phi_x)*Math.sin(phi_z);
    anode_mesh.position.x = (Gun.Anode_height - rotate_center_height)*Math.sin(phi_x)
    anode_mesh.position.z = (Gun.Anode_height - rotate_center_height)*Math.cos(phi_x)*Math.sin(phi_z);

    anode_mesh.rotation.x = -phi_z + Math.PI / 2;
    anode_mesh.rotation.z = phi_x
    
    anode_mesh.rotation.set( -phi_z + Math.PI / 2,0,phi_x);

    
    pointing_line.rotation.set(-phi_z,0,phi_x);
    pointing_line.position.set(Math.sin(phi_x) * World.Total_height,0,Math.sin(phi_z) * World.Total_height)
}

// rotate_gun(0,0.5);

//Set up shadow properties for the light
electron_beam.shadow.mapSize.width = 512; // default
electron_beam.shadow.mapSize.height = 512; // default
electron_beam.shadow.camera.near = 0.5; // default
electron_beam.shadow.camera.far = 500; // default
electron_beam.shadow.focus = 1; // default



//Create a sphere to indicate the position of the light
const sphereGeometry = new THREE.SphereGeometry(4);
const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff00ff } );
const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.castShadow = true; //default is false
sphere.receiveShadow = false; //default
sphere.rotateX(Math.PI);
sphere.position.y = World.Total_height - Gun.Anode_height + 5;
// scene.add( sphere );

const ground_anode_geometry = new THREE.RingGeometry( Aperture_size.Ground_anode, Outer_size,65536);
const ground_anode_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const ground_anode_mesh = new THREE.Mesh( ground_anode_geometry, ground_anode_material );
ground_anode_mesh.castShadow = true; //default is false
ground_anode_mesh.receiveShadow = false; //default
ground_anode_mesh.rotateX(Math.PI / 2);
ground_anode_mesh.position.y = World.Total_height - Aperture_posi.Ground_anode;
scene.add( ground_anode_mesh );

const min_hole_geometry = new THREE.RingGeometry( Aperture_size.Min_hole, Outer_size,65536);
const min_hole_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const min_hole_mesh = new THREE.Mesh( min_hole_geometry, min_hole_material );
min_hole_mesh.castShadow = true; //default is false
min_hole_mesh.receiveShadow = false; //default
min_hole_mesh.rotateX(Math.PI / 2);
min_hole_mesh.position.y = World.Total_height - Aperture_posi.Min_hole;
scene.add( min_hole_mesh );

const lock_1_geometry = new THREE.RingGeometry( Aperture_size.Lock_1, Outer_size,65536);
const lock_1_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const lock_1_mesh = new THREE.Mesh( lock_1_geometry, lock_1_material );
lock_1_mesh.castShadow = true; //default is false
lock_1_mesh.receiveShadow = false; //default
lock_1_mesh.rotateX(Math.PI / 2);
lock_1_mesh.position.y = World.Total_height - Aperture_posi.Lock_1;
scene.add( lock_1_mesh );

const lock_2_geometry = new THREE.RingGeometry( Aperture_size.Lock_2, Outer_size,65536);
const lock_2_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const lock_2_mesh = new THREE.Mesh( lock_2_geometry, lock_2_material );
lock_2_mesh.castShadow = true; //default is false
lock_2_mesh.receiveShadow = false; //default
lock_2_mesh.rotateX(Math.PI / 2);
lock_2_mesh.position.y = World.Total_height - Aperture_posi.Lock_2;
scene.add( lock_2_mesh );

const tube_geometry = new THREE.RingGeometry( Aperture_size.Tube, Outer_size,65536);
const tube_material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const tube_mesh = new THREE.Mesh( tube_geometry, tube_material );
tube_mesh.castShadow = true; //default is false
tube_mesh.receiveShadow = false; //default
tube_mesh.rotateX(Math.PI / 2);
tube_mesh.position.y = World.Total_height - Aperture_posi.Tube;
scene.add( tube_mesh );


//Create a plane that receives shadows (but does not cast them)
const planeGeometry = new THREE.PlaneGeometry( 300, 300 );
const planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } )
const plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.rotateY(Math.PI/2);
plane.rotateX(Math.PI/2*3);
plane.position.y = -0.1;
plane.receiveShadow = true;
scene.add( plane );


const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,0,1);
scene.add( directionalLight );
// directionalLight.intensity = 10;

function light_move()
{
    electron_beam.position.x = Number(document.getElementById("light_x").value);
    // light.position.y = Number(document.getElementById("light_y").value);
    electron_beam.position.z = Number(document.getElementById("light_z").value);
    // sphere.position.y = Number(document.getElementById("light_z").value);
    
    sphere.position.x = electron_beam.position.x;
    sphere.position.y = electron_beam.position.y;
    sphere.position.z = electron_beam.position.z;
    // sphere.position.y = 70
    sphere.position.y +=5;
}

// spin of one anode

function draw() {
    renderer_global.render(scene,camera_global);
    renderer_direct.render(scene,camera_direct);
    requestAnimationFrame(draw);
}

draw();

